#include "contact.h"

static int SearchByName(char* name, con* pContact)
{
	int i = 0;
	for (i = 0; i < pContact->sz; i++)
	{
		if (0 == strcmp(name, pContact->arr[i].name))
		{
			return i;
		}
	}
	return -1;
}

int CompareByName(const void* a, const void* b)
{
	return strcmp(((info*)a)->name, ((info*)b)->name);
}

void Menu()
{
	printf("\033[36m");
	printf("*****************************\n");
	printf("*********  Contacts  ********\n");
	printf("*****************************\n");
	printf("***  1.Add      2.Delete  ***\n");
	printf("***  3.Search   4.Modify  ***\n");
	printf("***  5.Sort     6.Display ***\n");
	printf("***        0.Exit         ***\n");
	printf("*****************************\n");
	printf("\033[0m");
}

void Init(con* pContact)
{
	if (pContact->sz >= (pContact->capa - 2) && pContact->capa != 0)
	{
		//printf("\033[31m%d\033[0m\n", pContact->capa);
		pContact->arr = (info*)realloc(pContact->arr, (pContact->capa) * sizeof(info) + ADDITION_SZ * sizeof(info));
		if (!pContact->arr)
		{
			printf("\033[31mFailed to add capacity : %s\033[0m\n", strerror(errno));
			assert(pContact->arr);
		}
		pContact->capa += ADDITION_SZ;
		//printf("\033[34m%d\033[0m\n", pContact->capa);
		memset((char*)(pContact->arr) + (pContact->capa + 1) * sizeof(info), 0, ADDITION_SZ * sizeof(info));
		//memset(pContact->arr, 0, pContact->capa * sizeof(info));
	}
	else if (0 == pContact->capa)
	{
		//printf("\033[33m%d\033[0m\n", pContact->capa);
		pContact->arr = (info*)malloc(DEFAULT_SZ * sizeof(info));
		if (!pContact->arr)
		{
			printf("\033[31mFailed to initialize : %s\033[0m\n", strerror(errno));
			assert(pContact->arr);
		}
		pContact->capa += DEFAULT_SZ;
		//printf("\033[32m%d\033[0m\n", pContact->capa);
		memset(pContact->arr, 0, DEFAULT_SZ * sizeof(info));
	}

	//memset(pContact->arr, 0, sizeof(pContact->arr));

}

void Add(con* pContact)
{
	//if (pContact->sz == ARR_M)
	//{
	//	printf("The contacts is full.\n");
	//	return;
	//}

	printf("\033[35mType the name.\033[0m\n");
	scanf("%[^\n]", (pContact->arr)[pContact->sz].name);
	while (getchar() != '\n');

	printf("\033[35mType the sex(0:Male/1:Female/2:Other).\033[0m\n");
	scanf("%d", &(pContact->arr)[pContact->sz].sex);
	while (getchar() != '\n');

	printf("\033[35mType the age.\033[0m\n");
	scanf("%d", &(pContact->arr)[pContact->sz].age);
	while (getchar() != '\n');

	printf("\033[35mType the tel.\033[0m\n");
	scanf("%[^\n]", (pContact->arr)[pContact->sz].tel);
	while (getchar() != '\n');

	printf("\033[35mType the address.\033[0m\n");
	scanf("%[^\n]", (pContact->arr)[pContact->sz].address);
	while (getchar() != '\n');

	pContact->sz++;
	printf("\033[32mSuccessfully added.\033[0m\n");
}

void Delete(con* pContact)
{
	if (0 == pContact->sz)
	{
		printf("\033[31mThere's nothing to delete here.\033[0m\n");
		return;
	}

	char name[NAME_M] = { 0 };
	printf("\033[35mType a contact to delete:>\033[0m");
	scanf("%[^\n]", name);
	int i = 0;
	int pos = SearchByName(name, pContact);

	if (-1 == pos)
	{
		printf("\033[31mTere's no one called %s.\033[0m\n", name);
		return;
	}

	for (; pos < (pContact->sz) - 1; pos++)
	{
		pContact->arr[pos] = pContact->arr[pos + 1];
	}
	(pContact->sz)--;
	printf("\033[32mSuccessfully deleted.\033[0m\n");
}

void Search(const con* pContact)
{
	if (0 == pContact->sz)
	{
		printf("\033[31mThere's nothing to search here.\033[0m\n");
		return;
	}
	char name[NAME_M] = { 0 };
	printf("\033[35mType a name to search:>\033[0m");
	scanf("%[^\n]", name);
	int i = SearchByName(name, pContact);
	if (-1 != i)
	{
		printf("\033[37mResults are as follows:\033[0m\n");
		printf("\033[33m%-20s%-8s%-5s%-12s%-20s\033[0m\n", "name", "sex", "age", "tel", "address");
		printf("\033[34m");
		printf("%-20s", pContact->arr[i].name);
		if (0 == pContact->arr[i].sex)
		{
			printf("%-8s", "Male");
		}
		else if (1 == pContact->arr[i].sex)
		{
			printf("%-8s", "Female");
		}
		else
		{
			printf("%-8s", "Other");
		}
		printf("%-5d", pContact->arr[i].age);
		printf("%-12s", pContact->arr[i].tel);
		printf("%-20s\n", pContact->arr[i].address);
		printf("\033[0m");
	}
	else
	{
		printf("\033[31mNothing was found.\033[0m\n");
	}

}

void Modify(con* pContact)
{
	if (0 == pContact->sz)
	{
		printf("\033[31mThere's nothing to modify here.\033[0m\n");
		return;
	}
	char name[NAME_M] = { 0 };
	printf("\033[35mType a name to modify:>\033[0m");
	scanf("%[^\n]", name);
	int pos = SearchByName(name, pContact);
	if (-1 == pos)
	{
		printf("\033[31mTere's no one called %s.\033[0m\n", name);
	}
	else
	{
		printf("\033[35mType the name:>\033[0m\n");
		scanf("%[^\n]", (pContact->arr)[pos].name);
		while (getchar() != '\n');

		printf("\033[35mType the sex(0:Male/1:Female/2:Other).\033[0m\n");
		scanf("%d", &(pContact->arr)[pos].sex);
		while (getchar() != '\n');

		printf("\033[35mType the age.\033[0m\n");
		scanf("%d", &(pContact->arr)[pos].age);
		while (getchar() != '\n');

		printf("\033[35mType the tel.\033[0m\n");
		scanf("%[^\n]", (pContact->arr)[pos].tel);
		while (getchar() != '\n');

		printf("\033[35mType the address.\033[0m\n");
		scanf("%[^\n]", (pContact->arr)[pos].address);
		while (getchar() != '\n');

		printf("\033[32mSuccessfully modified.\033[0m\n");
	}
}

void Sort(con* pContact)
{
	qsort(pContact->arr, pContact->sz, sizeof(info), CompareByName);
	printf("\033[32mSuccessfully sorted.\033[0m\n");
}

void Display(const con* pContact)
{
	int i = 0;
	printf("\033[33m%-20s%-8s%-5s%-12s%-20s\033[0m\n", "name", "sex", "age", "tel", "address");

	for (; i < pContact->sz; i++)
	{
		printf("\033[34m");
		printf("%-20s", pContact->arr[i].name);
		if (0 == pContact->arr[i].sex)
		{
			printf("%-8s", "Male");
		}
		else if (1 == pContact->arr[i].sex)
		{
			printf("%-8s", "Female");
		}
		else
		{
			printf("%-8s", "Other");
		}
		printf("%-5d", pContact->arr[i].age);
		printf("%-12s", pContact->arr[i].tel);
		printf("%-20s\n", pContact->arr[i].address);
		printf("\033[0m");
	}
}

void Save(con* pContact)
{
	//FILE* pf = fopen("data.txt", "w");
	FILE* pf = fopen("data.dat", "wb");
	if (!pf)
	{
		printf("\033[31mSaving failed.\033[0m\n");
		return;
	}
	int i = 0;
	for (i = 0; i < pContact->sz; i++)
	{
		//fprintf(pf, "%20s\n%1d\n%3d\n%12s\n%20s\n",
		//	(pContact->arr[i].name),
		//	(pContact->arr[i].sex),
		//	(pContact->arr[i].age),
		//	(pContact->arr[i].tel),
		//	(pContact->arr[i].address));
		fwrite(pContact->arr + i, sizeof(info), 1, pf);
	}
	fclose(pf);
	pf = NULL;
	printf("\033[32mSuccessfully saved.\033[0m\n");
}


void Load(con* pContact)
{
	//FILE* pf = fopen("data.txt", "r");
	FILE* pf = fopen("data.dat", "rb");
	if (!pf)
	{
		fopen("data.dat", "wb");
		fclose(pf);
		pf = fopen("data.dat", "rb");
	}
	if (!pf)
	{
		printf("\033[31mFailed to load the contact file.\033[0m\n");
		assert(pf);
	}
	int i = 0;
	Init(pContact);
	for (i = 0; /*fscanf(pf, "%[^\n]%01d%03d%[^\n]%[^\n]",
		&(pContact->arr[i].name),
		&(pContact->arr[i].sex),
		&(pContact->arr[i].age),
		&(pContact->arr[i].tel),
		&(pContact->arr[i].address)) != EOF*/ fread(pContact->arr + i, sizeof(info), 1, pf) == 1; i++)
	{
		Init(pContact);
		pContact->sz++;
	}
	printf("\033[32mSuccessfully loaded.\033[0m\n");
	fclose(pf);
	pf = NULL;
}